#ifndef __M_BUFF_H__
#define __M_BUFF_H__
#include <vector>
#include <iostream>
#include <assert.h>

#define DEFAULT_BUFFER_SIZE (1024*1024*1)
#define THRESHOLD_BUFFER__SIZE (1024*1024*8)
#define INCREMENT_BUFFER_SZIE (1024*1024*1)

class Buffer
{
public:
    Buffer()
        :_buffer(DEFAULT_BUFFER_SIZE),
        _reader_idx(0),
        _writer_idx(0)
    {}
    // 写入数据
    void push(const char *data, size_t len)
    {
        // 缓冲区空间不够 1.扩容（测试） 2.返回/阻塞
        // 1.固定大小，直接返回
        // if (len > writeableSize())
        // {
        //     return;
        // }
        // 2.动态空间，用于极限性能测试-扩容
        ensureEnoughSize(len);
        // 将数据拷贝缓冲区
        std::copy(data, data + len, &_buffer[_writer_idx]);
        // 当前写入位置向后偏移
        moveWriter(len);
    }
    // 返回可读数据起始位置
    const char *begin()
    {
        return &_buffer[_reader_idx];
    }
    // 返回可读数据长度
    size_t readableSize()
    {
        return _writer_idx - _reader_idx;
    }
    size_t writeableSize()
    {
        return _buffer.size() - _writer_idx;
    }
    // 读写指针向后偏移
    void moveReader(size_t len)
    {
        assert(len <= readableSize());
        _reader_idx += len;
    }

    // 重置读写位置，初始化缓冲区
    void reset()
    {
        _reader_idx = 0;
        _writer_idx = 0;
    }
    // 交换buffer
    void swap(Buffer& buffer)
    {
        _buffer.swap(buffer._buffer);
        std::swap(_reader_idx, buffer._reader_idx);
        std::swap(_writer_idx, buffer._writer_idx);
    }
    // 是否为空
    bool empty()
    {
        return _reader_idx == _writer_idx;
    }

private:
    // 空间扩容
    void ensureEnoughSize(size_t len)
    {
        // 不需要扩容
        if (len <= writeableSize()) 
        {
            return;
        }
        size_t newsize = 0;
        // 阈值下，翻倍增加
        if (_buffer.size() < THRESHOLD_BUFFER__SIZE)
        {
            newsize = _buffer.size() * 2 + len;
        }
        else
        {
            // 增量增加
            newsize = _buffer.size() + INCREMENT_BUFFER_SZIE + len;
        }
        _buffer.resize(newsize);
    }

    void moveWriter(size_t len)
    {
        assert(len + _writer_idx <= _buffer.size());
        _writer_idx += len;
    }
    
private:
    std::vector<char> _buffer;
    size_t _reader_idx;  // 可读数据指针，本质是下标
    size_t _writer_idx;
    size_t _len;
};
#endif